package com.mercury.ec.module.air.service.demandorder;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.mercury.ec.framework.common.pojo.PageResult;
import com.mercury.ec.framework.common.util.object.BeanUtils;
import com.mercury.ec.framework.web.core.util.WebFrameworkUtils;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandorder.*;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandprice.AirDemandPriceQuoteReqVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandprice.AirDemandPriceRespVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandroute.AirDemandRouteQuoteReqVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandroute.AirDemandRouteRespVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandroutesegment.AirDemandRouteSegmentQuoteReqVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandroutesegment.AirDemandRouteSegmentRespVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandscheme.AirDemandSchemeQuoteReqVO;
import com.mercury.ec.module.air.controller.admin.demandorder.vo.demandscheme.AirDemandSchemeRespVO;
import com.mercury.ec.module.air.dal.dataobject.demandorder.*;
import com.mercury.ec.module.air.dal.mysql.demandorder.*;
import com.mercury.ec.module.air.enums.AirDemandOrderStatusEnum;
import com.mercury.ec.module.air.enums.AirDemandRouteStatusEnum;
import com.mercury.ec.module.air.enums.AirDemandSchemeStatusEnum;
import com.mercury.ec.module.air.enums.CodingRuleNoConstants;
import com.mercury.ec.module.basic.dal.dataobject.customer.CustomerDO;
import com.mercury.ec.module.basic.dal.mysql.customer.CustomerMapper;
import com.mercury.ec.module.system.api.user.AdminUserApi;
import com.mercury.ec.module.system.api.user.dto.AdminUserRespDTO;
import com.mercury.framework.codingrule.core.util.CodingRuleFrameworkUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.mercury.ec.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.mercury.ec.module.air.enums.ErrorCodeConstants.*;

/**
 * 机票需求订单 Service 实现类
 *
 * @author hesx
 */
@Service
@Validated
public class AirDemandOrderServiceImpl implements AirDemandOrderService {

    @Resource
    private AirDemandOrderMapper airDemandOrderMapper;
    @Resource
    private AirDemandSchemeMapper airDemandSchemeMapper;
    @Resource
    private AirDemandRouteMapper airDemandRouteMapper;
    @Resource
    private AirDemandRouteSegmentMapper airDemandRouteSegmentMapper;
    @Resource
    private AirDemandPriceMapper airDemandPriceMapper;
    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private AdminUserApi userApi;

    @Override
    public Long createAirDemandOrder(AirDemandOrderCreateReqVO createReqVO) {
        // 生成编号
        String no = CodingRuleFrameworkUtil.genericNo(CodingRuleNoConstants.AIR_DEMAND_ORDER_NO, null);
        // 校验
        validateDemandOrderForCreateOrUpdate(null, no);
        // 插入
        AirDemandOrderDO airDemandOrderDO = BeanUtils.toBean(createReqVO, AirDemandOrderDO.class);
        // 补充信息
        CustomerDO customerDO = customerMapper.selectById(createReqVO.getCustomerId());
        // 当前用户
        AdminUserRespDTO user = userApi.getUser(WebFrameworkUtils.getLoginUserId());
        airDemandOrderDO.setNo(no);
        airDemandOrderDO.setCustomerNo(customerDO.getNo());
        airDemandOrderDO.setCustomerName(customerDO.getShortName());
        airDemandOrderDO.setBookUserId(user.getId());
        airDemandOrderDO.setBookDeptId(user.getDeptId());
        airDemandOrderDO.setBookTime(LocalDateTime.now());
        airDemandOrderDO.setLocked(false);
        airDemandOrderDO.setStatus(createReqVO.getSubmit() ? AirDemandOrderStatusEnum.WAIT_QUOTE.getStatus() : AirDemandOrderStatusEnum.WAIT_SUBMIT.getStatus());
        airDemandOrderMapper.insert(airDemandOrderDO);
        // 返回
        return airDemandOrderDO.getId();
    }

    @Override
    public void updateAirDemandOrder(AirDemandOrderUpdateReqVO updateReqVO) {
        // 校验
        validateDemandOrderForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getNo());
        // 补充信息
        CustomerDO customerDO = customerMapper.selectById(updateReqVO.getCustomerId());
        // 当前用户
        AirDemandOrderDO updateObj = BeanUtils.toBean(updateReqVO, AirDemandOrderDO.class);
        updateObj.setCustomerNo(customerDO.getNo());
        updateObj.setCustomerName(customerDO.getShortName());
        updateObj.setStatus(updateReqVO.getSubmit() ? AirDemandOrderStatusEnum.WAIT_QUOTE.getStatus() : AirDemandOrderStatusEnum.WAIT_SUBMIT.getStatus());
        // 更新
        airDemandOrderMapper.updateById(updateObj);
    }

    @Override
    public void submitAirDemandOrder(AirDemandOrderSubmitReqVO submitReqVO) {
        // 校验存在
        AirDemandOrderDO airDemandOrderDO = validateDemandOrderExists(submitReqVO.getId());
        if (AirDemandOrderStatusEnum.isCanceled(airDemandOrderDO.getStatus())) {
            throw exception(AIR_DEMAND_ORDER_CANCELED_NOT_ALLOW_SUBMIT);
        }
        if (!AirDemandOrderStatusEnum.isWaitSubmit(airDemandOrderDO.getStatus())) {
            throw exception(AIR_DEMAND_ORDER_SUBMITED_NOT_ALLOW_SUBMIT);
        }
        // 更新状态
        airDemandOrderDO.setStatus(AirDemandOrderStatusEnum.WAIT_QUOTE.getStatus());
        airDemandOrderMapper.updateById(airDemandOrderDO);
    }

    @Override
    public void cancelAirDemandOrder(AirDemandOrderCancelReqVO cancelReqVO) {
        // 校验存在
        AirDemandOrderDO airDemandOrderDO = validateDemandOrderExists(cancelReqVO.getId());
        if (AirDemandOrderStatusEnum.isCanceled(airDemandOrderDO.getStatus())) {
            throw exception(AIR_DEMAND_ORDER_CANCELED_NOT_ALLOW_CANCEL);
        }
        if (!AirDemandOrderStatusEnum.isWaitSubmit(airDemandOrderDO.getStatus())) {
            throw exception(AIR_DEMAND_ORDER_SUBMITED_NOT_ALLOW_CANCEL);
        }
        // 更新状态
        airDemandOrderDO.setStatus(AirDemandOrderStatusEnum.CANCELED.getStatus());
        airDemandOrderMapper.updateById(airDemandOrderDO);
    }

    @Override
    public void lockAirDemandOrder(AirDemandOrderLockReqVO lockReqVO) {
        // 校验存在
        AirDemandOrderDO airDemandOrderDO = validateDemandOrderExists(lockReqVO.getId());
        if (airDemandOrderDO.getLocked()) {
            throw exception(AIR_DEMAND_ORDER_LOCKED_NOT_ALLOW_LOCK, Optional.ofNullable(userApi.getUser(airDemandOrderDO.getLockUserId())).map(AdminUserRespDTO::getNickname).orElse(null));
        }
        // 当前用户
        AdminUserRespDTO user = userApi.getUser(WebFrameworkUtils.getLoginUserId());
        // 更新状态
        airDemandOrderDO.setLocked(true);
        airDemandOrderDO.setLockUserId(user.getId());
        airDemandOrderDO.setLockDeptId(user.getDeptId());
        airDemandOrderDO.setLockTime(LocalDateTime.now());
        airDemandOrderMapper.updateById(airDemandOrderDO);
    }

    @Override
    public void unlockAirDemandOrder(AirDemandOrderLockReqVO lockReqVO) {
        // 校验存在
        AirDemandOrderDO airDemandOrderDO = validateDemandOrderExists(lockReqVO.getId());
        if (!airDemandOrderDO.getLocked()) {
            throw exception(AIR_DEMAND_ORDER_UNLOCKED_NOT_ALLOW_UNLOCK);
        }
        // 谁锁谁解锁
        AdminUserRespDTO user = userApi.getUser(WebFrameworkUtils.getLoginUserId());
        if (!Objects.equals(airDemandOrderDO.getLockUserId(), user.getId())) {
            throw exception(AIR_DEMAND_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, Optional.ofNullable(userApi.getUser(airDemandOrderDO.getLockUserId())).map(AdminUserRespDTO::getNickname).orElse(null));
        }
        // 更新状态
        airDemandOrderMapper.update(new LambdaUpdateWrapper<AirDemandOrderDO>()
                .set(AirDemandOrderDO::getLocked, false)
                .set(AirDemandOrderDO::getLockUserId, null)
                .set(AirDemandOrderDO::getLockDeptId, null)
                .set(AirDemandOrderDO::getLockTime, null)
                .eq(AirDemandOrderDO::getId, lockReqVO.getId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void quoteAirDemandOrder(AirDemandOrderQuoteReqVO quoteReqVO) {
        // 校验
        AirDemandOrderDO airDemandOrderDO = validateDemandOrderExists(quoteReqVO.getDemandId());
        AdminUserRespDTO user = userApi.getUser(WebFrameworkUtils.getLoginUserId());
        if (AirDemandOrderStatusEnum.isWaitSubmit(airDemandOrderDO.getStatus())) {
            throw exception(AIR_DEMAND_ORDER_NOT_SUBMIT_NOT_ALLOW_QUOTE);
        }
        if (!airDemandOrderDO.getLocked()) {
            throw exception(AIR_DEMAND_ORDER_NOT_LOCKER_NOT_ALLOW_QUOTE);
        } else {
            if (!Objects.equals(airDemandOrderDO.getLockUserId(), user.getId())) {
                AdminUserRespDTO lockUser = userApi.getUser(airDemandOrderDO.getLockUserId());
                throw exception(AIR_DEMAND_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, lockUser.getNickname());
            }
        }
        // 校验编号
        List<AirDemandSchemeQuoteReqVO> demandSchemes = quoteReqVO.getDemandSchemes();
        demandSchemes.stream().collect(Collectors.groupingBy(AirDemandSchemeQuoteReqVO::getSerialNo, Collectors.counting())).forEach((serialNo, count) -> {
            if (count > 1) {
                throw exception(AIR_DEMAND_SCHEME_SERIALNO_NOT_UNIQUE, serialNo);
            }
        });
        demandSchemes.forEach(ds -> {
            List<AirDemandRouteQuoteReqVO> demandRoutes = ds.getDemandRoutes();
            demandRoutes.stream().collect(Collectors.groupingBy(AirDemandRouteQuoteReqVO::getSerialNo, Collectors.counting())).forEach((serialNo, count) -> {
                if (count > 1) {
                    throw exception(AIR_DEMAND_ROUTE_SERIALNO_NOT_UNIQUE, serialNo);
                }
            });
            demandRoutes.forEach(dr -> {
                List<AirDemandRouteSegmentQuoteReqVO> demandRouteSegments = dr.getDemandRouteSegments();
                demandRouteSegments.stream().collect(Collectors.groupingBy(AirDemandRouteSegmentQuoteReqVO::getSerialNo, Collectors.counting())).forEach((serialNo, count) -> {
                    if (count > 1) {
                        throw exception(AIR_DEMAND_ROUTE_SEGMENT_SERIALNO_NOT_UNIQUE, serialNo);
                    }
                });
                List<AirDemandPriceQuoteReqVO> demandPrices = dr.getDemandPrices();
                demandPrices.stream().collect(Collectors.groupingBy(AirDemandPriceQuoteReqVO::getPassengerType, Collectors.counting())).forEach((passengerType, count) -> {
                    if (count > 1) {
                        throw exception(AIR_DEMAND_PRICE_PASSENGER_TYPE_NOT_UNIQUE, passengerType);
                    }
                });
            });
        });

        // 删除已存在数据
        airDemandSchemeMapper.deleteByDemandId(quoteReqVO.getDemandId());
        airDemandRouteMapper.deleteByDemandId(quoteReqVO.getDemandId());
        airDemandRouteSegmentMapper.deleteByDemandId(quoteReqVO.getDemandId());
        airDemandPriceMapper.deleteByDemandId(quoteReqVO.getDemandId());

        // 组装/保存数据
        List<AirDemandSchemeDO> insertAirDemandSchemes = new ArrayList<>();
        for (AirDemandSchemeQuoteReqVO ds : demandSchemes) {
            Long demandSchemeId = IdWorker.getId();
            // 组装行程
            List<AirDemandRouteDO> insertAirDemandRoutes = new ArrayList<>();
            for (AirDemandRouteQuoteReqVO dr : ds.getDemandRoutes()) {
                Long demandRouteId = IdWorker.getId();
                AirDemandRouteDO airDemandRouteDO = BeanUtils.toBean(dr, AirDemandRouteDO.class);
                airDemandRouteDO.setId(demandRouteId);
                airDemandRouteDO.setDemandId(quoteReqVO.getDemandId());
                airDemandRouteDO.setDemandSchemeId(demandSchemeId);
                airDemandRouteDO.setBookUserId(user.getId());
                airDemandRouteDO.setBookDeptId(user.getDeptId());
                airDemandRouteDO.setBookTime(LocalDateTime.now());
                airDemandRouteDO.setQuoteUserId(user.getId());
                airDemandRouteDO.setQuoteDeptId(user.getDeptId());
                airDemandRouteDO.setQuoteTime(LocalDateTime.now());
                airDemandRouteDO.setStatus(dr.getStatus() == null ? AirDemandRouteStatusEnum.WAIT_PRICING.getStatus() : ds.getStatus());
                insertAirDemandRoutes.add(airDemandRouteDO);

                // 组装/保存航段
                for (AirDemandRouteSegmentQuoteReqVO drs : dr.getDemandRouteSegments()) {
                    drs.setDemandId(quoteReqVO.getDemandId());
                    drs.setDemandSchemeId(demandSchemeId);
                    drs.setDemandRouteId(demandRouteId);
                    airDemandRouteSegmentMapper.insert(BeanUtils.toBean(drs, AirDemandRouteSegmentDO.class));
                }

                // 组装/保存价格
                for (AirDemandPriceQuoteReqVO dp : dr.getDemandPrices()) {
                    dp.setDemandId(quoteReqVO.getDemandId());
                    dp.setDemandSchemeId(demandSchemeId);
                    dp.setDemandRouteId(demandRouteId);
                    airDemandPriceMapper.insert(BeanUtils.toBean(dp, AirDemandPriceDO.class));
                }
            }

            // 保存行程
            airDemandRouteMapper.insertBatch(insertAirDemandRoutes);

            // 组装方案
            AirDemandSchemeDO airDemandSchemeDO = BeanUtils.toBean(ds, AirDemandSchemeDO.class);
            airDemandSchemeDO.setId(demandSchemeId);
            airDemandSchemeDO.setDemandId(quoteReqVO.getDemandId());
            airDemandSchemeDO.setBookUserId(user.getId());
            airDemandSchemeDO.setBookDeptId(user.getDeptId());
            airDemandSchemeDO.setBookTime(LocalDateTime.now());
            airDemandSchemeDO.setFinallyQuoteDeptId(user.getId());
            airDemandSchemeDO.setFinallyQuoteDeptId(user.getDeptId());
            airDemandSchemeDO.setFinallyQuoteTime(LocalDateTime.now());
            Map<Integer, List<AirDemandRouteDO>> routeStatusMap = insertAirDemandRoutes.stream().collect(Collectors.groupingBy(AirDemandRouteDO::getStatus));
            airDemandSchemeDO.setStatus(routeStatusMap.size() > 1 ? AirDemandSchemeStatusEnum.WAIT_PRICING.getStatus() : routeStatusMap.keySet().stream().findFirst().get());
            insertAirDemandSchemes.add(airDemandSchemeDO);
        }

        // 保存方案
        airDemandSchemeMapper.insertBatch(insertAirDemandSchemes);

        // 更新订单
        // 转换订单状态
        Map<Integer, List<AirDemandSchemeDO>> schemeStatusMap = insertAirDemandSchemes.stream().collect(Collectors.groupingBy(AirDemandSchemeDO::getStatus));
        Integer status = AirDemandOrderStatusEnum.WAIT_PRICING.getStatus();
        if (schemeStatusMap.size() == 1) {
            Integer schemeStatus = schemeStatusMap.keySet().stream().findFirst().get();
            if (AirDemandSchemeStatusEnum.isWaitPricing(schemeStatus)) {
                status = AirDemandOrderStatusEnum.WAIT_PRICING.getStatus();
            } else if (AirDemandSchemeStatusEnum.isPriced(schemeStatus)) {
                status = AirDemandOrderStatusEnum.PRICED.getStatus();
            } else if (AirDemandSchemeStatusEnum.isCanceled(schemeStatus)) {
                status = AirDemandOrderStatusEnum.CANCELED.getStatus();
            }
        }
        airDemandOrderMapper.update(new LambdaUpdateWrapper<AirDemandOrderDO>().eq(AirDemandOrderDO::getId, airDemandOrderDO.getId())
                .set(AirDemandOrderDO::getFinallyQuoteUserId, user.getId())
                .set(AirDemandOrderDO::getFinallyQuoteDeptId, user.getDeptId())
                .set(AirDemandOrderDO::getFinallyQuoteTime, LocalDateTime.now())
                .set(AirDemandOrderDO::getLocked, false)
                .set(AirDemandOrderDO::getLockUserId, null)
                .set(AirDemandOrderDO::getLockDeptId, null)
                .set(AirDemandOrderDO::getLockTime, null)
                .set(AirDemandOrderDO::getStatus, status)
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pricingAirDemandOrder(AirDemandOrderPricingReqVO pricingReqVO) {
        // 校验
        Long demandId = pricingReqVO.getDemandPrices().get(0).getDemandId();
        Long demandSchemeId = pricingReqVO.getDemandPrices().get(0).getDemandSchemeId();
        Long demandRouteId = pricingReqVO.getDemandPrices().get(0).getDemandRouteId();
        AirDemandOrderDO airDemandOrderDO = validateDemandOrderExists(demandId);
        AdminUserRespDTO user = userApi.getUser(WebFrameworkUtils.getLoginUserId());
        if (AirDemandOrderStatusEnum.isWaitQuote(airDemandOrderDO.getStatus())) {
            throw exception(AIR_DEMAND_ORDER_NOT_QUOTE_NOT_ALLOW_PRICING);
        }
        if (!airDemandOrderDO.getLocked()) {
            throw exception(AIR_DEMAND_ORDER_NOT_LOCKER_NOT_ALLOW_PRICING);
        } else {
            if (!Objects.equals(airDemandOrderDO.getLockUserId(), user.getId())) {
                throw exception(AIR_DEMAND_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, Optional.ofNullable(userApi.getUser(airDemandOrderDO.getLockUserId())).map(AdminUserRespDTO::getNickname).orElse(null));
            }
        }
        AirDemandSchemeDO airDemandSchemeDO = airDemandSchemeMapper.selectById(demandSchemeId);
        if (airDemandSchemeDO == null) {
            throw exception(AIR_DEMAND_SCHEME_NOT_EXISTS);
        }
        AirDemandRouteDO airDemandRouteDO = airDemandRouteMapper.selectById(demandRouteId);
        if (airDemandRouteDO == null) {
            throw exception(AIR_DEMAND_ROUTE_NOT_EXISTS);
        }

        // 更新价格 todo 是否需要校验前端传值 hesx
        airDemandPriceMapper.updateBatch(BeanUtils.toBean(pricingReqVO.getDemandPrices(), AirDemandPriceDO.class));

        // 更新行程
        airDemandRouteDO.setPricingUserId(user.getId());
        airDemandRouteDO.setPricingDeptId(user.getDeptId());
        airDemandRouteDO.setPricingTime(LocalDateTime.now());
        airDemandRouteDO.setStatus(AirDemandRouteStatusEnum.PRICED.getStatus());
        airDemandRouteMapper.updateById(airDemandRouteDO);

        // 更新方案
        long waitPriceCount = airDemandRouteMapper.selectList(new LambdaUpdateWrapper<AirDemandRouteDO>()
                .eq(AirDemandRouteDO::getDemandSchemeId, demandRouteId)
                .eq(AirDemandRouteDO::getStatus, AirDemandRouteStatusEnum.WAIT_PRICING.getStatus())).stream().count();
        airDemandSchemeDO.setFinallyPricingUserId(user.getId());
        airDemandSchemeDO.setFinallyPricingDeptId(user.getDeptId());
        airDemandSchemeDO.setFinallyPricingTime(LocalDateTime.now());
        airDemandSchemeDO.setStatus(waitPriceCount > 0 ? AirDemandSchemeStatusEnum.WAIT_PRICING.getStatus() : AirDemandSchemeStatusEnum.PRICED.getStatus());
        airDemandSchemeMapper.updateById(airDemandSchemeDO);

        // 更新订单
        waitPriceCount = airDemandSchemeMapper.selectList(new LambdaUpdateWrapper<AirDemandSchemeDO>()
                .eq(AirDemandSchemeDO::getDemandId, demandId)
                .eq(AirDemandSchemeDO::getStatus, AirDemandRouteStatusEnum.WAIT_PRICING.getStatus())).stream().count();
        airDemandOrderMapper.update(new LambdaUpdateWrapper<AirDemandOrderDO>().eq(AirDemandOrderDO::getId, airDemandOrderDO.getId())
                .set(AirDemandOrderDO::getFinallyPricingUserId, user.getId())
                .set(AirDemandOrderDO::getFinallyPricingDeptId, user.getDeptId())
                .set(AirDemandOrderDO::getFinallyPricingTime, LocalDateTime.now())
                .set(AirDemandOrderDO::getLocked, false)
                .set(AirDemandOrderDO::getLockUserId, null)
                .set(AirDemandOrderDO::getLockDeptId, null)
                .set(AirDemandOrderDO::getLockTime, null)
                .set(AirDemandOrderDO::getStatus, waitPriceCount > 0 ? AirDemandOrderStatusEnum.WAIT_PRICING.getStatus() : AirDemandOrderStatusEnum.PRICED.getStatus())
        );
    }

    @Override
    public void deleteAirDemandOrder(Long id) {
        // 校验存在
        validateDemandOrderExists(id);
        // 删除
        airDemandOrderMapper.deleteById(id);
    }

    private AirDemandOrderDO validateDemandOrderExists(Long id) {
        if (id == null) {
            return null;
        }
        AirDemandOrderDO airDemandOrderDO = airDemandOrderMapper.selectById(id);
        if (airDemandOrderDO == null) {
            throw exception(AIR_DEMAND_ORDER_NOT_EXISTS);
        }
        return airDemandOrderDO;
    }

    private void validateDemandOrderUnique(Long id, String no) {
        if (StrUtil.isBlank(no)) {
            return;
        }
        AirDemandOrderDO airDemandOrderDO = airDemandOrderMapper.selectByNo(no);
        if (airDemandOrderDO == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(AIR_DEMAND_ORDER_NO_EXISTS);
        }
        if (!airDemandOrderDO.getId().equals(id)) {
            throw exception(AIR_DEMAND_ORDER_NO_EXISTS);
        }
    }

    private void validateDemandOrderForCreateOrUpdate(Long id, String no) {
        // 校验存在
        validateDemandOrderExists(id);
        // 校验唯一
        validateDemandOrderUnique(id, no);
    }

    @Override
    public AirDemandOrderRespVO getAirDemandOrder(Long id) {
        AirDemandOrderRespVO airDemandOrderRespVO = airDemandOrderMapper.selectAirDemandOrderById(id);
        if (airDemandOrderRespVO != null) {
            // 方案
            List<AirDemandSchemeRespVO> airDemandSchemeRespVOS = airDemandSchemeMapper.selectByDemandId(id);
            if (CollUtil.isNotEmpty(airDemandSchemeRespVOS)) {
                // 行程
                List<AirDemandRouteRespVO> airDemandRouteRespVOS = airDemandRouteMapper.selectByDemandId(id);
                // 航段
                List<AirDemandRouteSegmentRespVO> airDemandRouteSegmentRespVOS = airDemandRouteSegmentMapper.selectByDemandId(id);
                // 价格
                List<AirDemandPriceRespVO> airDemandPriceRespVOS = airDemandPriceMapper.selectByDemandId(id);
                // 组装
                airDemandSchemeRespVOS.forEach(ds -> {
                    List<AirDemandRouteRespVO> demandRouteRespVOS = airDemandRouteRespVOS.stream().filter(dr -> ds.getId().equals(dr.getDemandSchemeId())).collect(Collectors.toList());
                    demandRouteRespVOS.forEach(dr -> {
                        dr.setDemandRouteSegments(airDemandRouteSegmentRespVOS.stream().filter(drs -> dr.getId().equals(drs.getDemandRouteId())).collect(Collectors.toList()));
                        dr.setDemandPrices(airDemandPriceRespVOS.stream().filter(dp -> dr.getId().equals(dp.getDemandRouteId())).collect(Collectors.toList()));
                    });
                    ds.setDemandRoutes(demandRouteRespVOS);
                });
            }
            airDemandOrderRespVO.setDemandSchemes(airDemandSchemeRespVOS);
        }
        return airDemandOrderRespVO;
    }

    @Override
    public PageResult<AirDemandOrderRespVO> getAirDemandOrderPage(AirDemandOrderPageReqVO pageReqVO) {
        return airDemandOrderMapper.selectPage(pageReqVO);
    }

    @Override
    public Map<Integer, Long> getAirDemandOrderCountByStatus(AirDemandOrderPageReqVO pageReqVO) {
        List<Map<String, Object>> countList = airDemandOrderMapper.selectAirDemandOrderCountByStatus(pageReqVO);
        Map<Integer, Long> countMap = new HashMap<>();
        countMap.put(0, 0L);
        countMap.put(10, 0L);
        countMap.put(20, 0L);
        countMap.put(30, 0L);
        countMap.put(40, 0L);
        countMap.put(50, 0L);
        Long total = 0L; // 全部
        for (Map<String, Object> p : countList) {
            countMap.put((Integer) p.get("status"), (Long) p.get("count"));
            total += NumberUtil.nullToZero((Long) p.get("count"));
        }
        countMap.put(1000, total);
        return countMap;
    }

}
